home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
WINPROGS
/
WINSRC20.ZIP
/
FRACSUBR.C
< prev
next >
Wrap
Text File
|
1990-09-10
|
32KB
|
984 lines
/*
FRACSUBR.C contains subroutines which belong primarily to CALCFRAC.C and
FRACTALS.C, i.e. which are non-fractal-specific fractal engine subroutines.
*/
#include <stdio.h>
#include <stdarg.h>
#include <float.h>
#include "fractint.h"
#include "fractype.h"
#include "mpmath.h"
/* routines in this module */
void calcfracinit(void);
void adjust_corner(void);
int alloc_resume(int,int);
int put_resume(int,...);
int start_resume(void);
int get_resume(int,...);
void end_resume(void);
void iplot_orbit(long,long,int);
void plot_orbit(double,double,int);
void scrub_orbit(void);
int add_worklist(int,int,int,int,int,int,int);
void tidy_worklist(void);
int ssg_blocksize(void);
void symPIplot(int,int,int);
void symPIplot2J(int,int,int);
void symPIplot4J(int,int,int);
void symplot2(int,int,int);
void symplot2Y(int,int,int);
void symplot2J(int,int,int);
void symplot4(int,int,int);
void symplot2basin(int,int,int);
void symplot4basin(int,int,int);
void get_julia_attractor(double,double);
static void adjust_to_limits(double);
static void smallest_add(double *);
static int ratio_bad(double,double);
static void plotdorbit(double,double,int);
static int combine_worklist(void);
extern int calc_status; /* status of calculations */
extern char far *resume_info; /* pointer to resume info if allocated */
int resume_len; /* length of resume info */
static int resume_offset; /* offset in resume info gets */
extern double plotmx1,plotmx2,plotmy1,plotmy2; /* real->screen conversion */
extern int orbit_ptr; /* pointer into save_orbit array */
extern int far *save_orbit; /* array to save orbit values */
extern int orbit_color; /* XOR color */
extern int num_worklist; /* resume worklist for standard engine */
extern int fractype; /* fractal type */
extern char stdcalcmode; /* '1', '2', 'g', 'b' */
extern char floatflag; /* floating-point fractals? */
extern int integerfractal; /* TRUE if fractal uses integer math */
extern struct workliststuff worklist[MAXCALCWORK];
extern int sxdots,sydots; /* # of dots on the physical screen */
extern int sxoffs,syoffs; /* physical top left of logical screen */
extern int xdots, ydots; /* # of dots on the logical screen */
extern int colors; /* maximum colors available */
extern long fudge; /* fudge factor (2**n) */
extern int bitshift; /* bit shift for fudge */
extern double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* corners */
extern long xmin, xmax, ymin, ymax, x3rd, y3rd; /* integer equivs */
extern int maxit; /* try this many iterations */
extern int attractors; /* number of finite attractors */
extern struct complex attr[]; /* finite attractor vals (f.p) */
extern struct lcomplex lattr[]; /* finite attractor vals (int) */
extern struct complex old,new;
extern struct lcomplex lold,lnew;
extern double tempsqrx,tempsqry;
extern long ltempsqrx,ltempsqry;
extern int xxstart,xxstop; /* these are same as worklist, */
extern int yystart,yystop,yybegin; /* declared as separate items */
extern int periodicitycheck;
extern int basin;
extern int finattract;
extern int pixelpi; /* value of pi in pixels */
extern double closenuff;
extern long lclosenuff;
extern int ixstart, ixstop, iystart, iystop;
extern int color;
extern int decomp[];
extern double potparam[3]; /* three potential parameters*/
extern int distest; /* non-zero if distance estimator */
extern double param[4]; /* up to four parameters */
extern int invert; /* non-zero if inversion active */
extern int biomorph;
extern int debugflag; /* internal use only - you didn't see this */
extern long creal, cimag; /* for calcmand */
extern long delx, dely; /* screen pixel increments */
extern long delx2, dely2; /* screen pixel increments */
extern double delxx, delyy; /* screen pixel increments */
extern double delxx2, delyy2; /* screen pixel increments */
extern long delmin; /* for calcfrac/calcmand */
extern double ddelmin; /* same as a double */
extern int potflag; /* continuous potential flag */
extern int bailout;
extern double rqlim;
extern double dxsize, dysize; /* xdots-1, ydots-1 */
extern long far *lx0, far *ly0; /* x, y grid */
extern long far *lx1, far *ly1; /* adjustment for rotate */
/* note that lx1 & ly1 values can overflow into sign bit; since */
/* they're used only to add to lx0/ly0, 2s comp straightens it out */
extern double far *dx0, far *dy0; /* floating pt equivs */
extern double far *dx1, far *dy1;
extern char usr_floatflag;
extern char usr_stdcalcmode;
extern int usr_periodicitycheck;
extern int usr_distest;
extern int StandardFractal(void);
extern int calcmand(void);
#define FUDGEFACTOR 29 /* fudge all values up by 2**this */
#define FUDGEFACTOR2 24 /* (or maybe this) */
void calcfracinit() /* initialize a *pile* of stuff for fractal calculation */
{
int i;
double ftemp;
init_restart:
/* the following variables may be forced to a different setting due to
calc routine constraints; usr_xxx is what the user last said is wanted,
xxx is what we actually do in the current situation */
stdcalcmode = usr_stdcalcmode;
periodicitycheck = usr_periodicitycheck;
distest = usr_distest;
floatflag = usr_floatflag;
if (distest) /* force floating point for dist est */
floatflag = 1;
potflag = 0;
if (potparam[0] != 0.0
&& colors >= 256
&& (fractalspecific[fractype].calctype == StandardFractal
|| fractalspecific[fractype].calctype == calcmand))
potflag = 1;
if (floatflag) { /* ensure type matches floatflag */
if (fractalspecific[fractype].isinteger != 0
&& fractalspecific[fractype].tofloat != NOFRACTAL)
fractype = fractalspecific[fractype].tofloat;
}
else {
if (fractalspecific[fractype].isinteger == 0
&& fractalspecific[fractype].tofloat != NOFRACTAL)
fractype = fractalspecific[fractype].tofloat;
}
integerfractal = fractalspecific[fractype].isinteger;
if (potflag && potparam[2] != 0.0)
rqlim = potparam[2];
else if (decomp[0] > 0 && decomp[1] > 0)
rqlim = (double)decomp[1];
else if (bailout) /* user input bailout */
rqlim = bailout;
else if (biomorph != -1) /* biomorph benefits from larger bailout */
rqlim = 100;
else if (distest) {
rqlim = 100000.0;
if (fractype == FPMANZTOZPLUSZPWR || fractype == FPJULZTOZPLUSZPWR)
rqlim = 100; /* reduce it to avoid fp math overflow */
}
else
rqlim = fractalspecific[fractype].orbit_bailout;
if (integerfractal) /* the bailout limit mustn't be too high here */
if (rqlim > 127.0) rqlim = 127.0;
if (fractalspecific[fractype].flags&NOROTATE != 0) {
/* ensure min<max and unrotated rectangle */
if (xxmin > xxmax) { ftemp = xxmax; xxmax = xxmin; xxmin = ftemp; }
if (yymin > yymax) { ftemp = yymax; yymax = yymin; yymin = ftemp; }
xx3rd = xxmin; yy3rd = yymin;
}
/* set up bitshift for integer math */
bitshift = FUDGEFACTOR2; /* by default, the smaller shift */
if (integerfractal > 1) /* use specific override from table */
bitshift = integerfractal;
if (integerfractal == 0) /* float? */
if ((i = fractalspecific[fractype].tofloat) != NOFRACTAL) /* -> int? */
if (fractalspecific[i].isinteger > 1) /* specific shift? */
bitshift = fractalspecific[i].isinteger;
if (fractype == MANDEL || fractype == JULIA) { /* adust shift bits if.. */
if (potflag == 0 /* not using potential */
&& (fractype != MANDEL /* and not an int mandel */
|| (param[0] == 0.0 && param[1] == 0.0)) /* w/ "fudged" params */
&& !invert /* and not inverting */
&& biomorph == -1 /* and not biomorphing */
&& rqlim <= 4.0 /* and bailout not too high */
&& debugflag != 1234) /* and not debugging */
bitshift = FUDGEFACTOR; /* use the larger bitshi